package com.sun.xacml.cond;

/*
 * @(#)DayOfWeekIsIn.java
 *
 * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistribution of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 * 
 *   2. Redistribution in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed or intended for use in
 * the design, construction, operation or maintenance of any nuclear facility.
 */

import com.sun.xacml.EvaluationCtx;

import com.sun.xacml.attr.AttributeSelector;
import com.sun.xacml.attr.AttributeValue;
import com.sun.xacml.attr.BagAttribute;
import com.sun.xacml.attr.BooleanAttribute;
import com.sun.xacml.attr.DateAttribute;
import com.sun.xacml.attr.StringAttribute;
import com.sun.xacml.cond.Evaluatable;
import com.sun.xacml.cond.EvaluationResult;
import com.sun.xacml.cond.FunctionBase;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * This class implements the proposed day-of-week-is-in function, which takes many
 * dayofweek values and returns true if the first value is equal to other.
 * <p> * 
 */
public class DayOfWeekIsIn extends FunctionBase {
	/**
	 * The identifier for this function
	 */
	public static final String NAME = "urn:oasis:names:tc:xacml:2.0:function:day-of-week-is-in";

	/**
	 * Default constructor.
	 */
	public DayOfWeekIsIn() {
		super(NAME, 0, DateAttribute.identifier, false, -1, BooleanAttribute.identifier, false);
	}

	/**
	 * Evaluates the day-of-week-is-in function, which takes
	 * <code>DateAttribute</code> value and more <code> StringAttribute</code>
	 * values. This function return true if the first value falls between the
	 * second and third values (ie., on or after the second time and on or
	 * before the third time).
	 * 
	 * @param inputs
	 *            a <code>List</code> of <code>Evaluatable</code> objects
	 *            representing the arguments passed to the function
	 * @param context
	 *            the respresentation of the request
	 * 
	 * @return an <code>EvaluationResult</code> containing true or false
	 */
	public EvaluationResult evaluate(List inputs, EvaluationCtx context) {

		ArrayList<AttributeValue> argValues = new ArrayList();
		
		EvaluationResult result = evalArgs(inputs, context, argValues);
		int[] strDates = new int[argValues.size() - 1];
		
		// check if any errors occured while resolving the inputs
		if (result != null)
			return result;
		DateAttribute attr = (DateAttribute) (argValues.get(0));
		int middleDay = attr.getDayOfWeek();
				
		//chuyen gia tri chuoi sang gia tri int 
		for (int i = 1; i < argValues.size(); i++) {
			if (((StringAttribute) argValues.get(i)).getValue().equals("Sunday"))
				strDates[i - 1] = 0;
			else if (((StringAttribute) argValues.get(i)).getValue().equals("Monday"))
				strDates[i - 1] = 1;
			else if (((StringAttribute) argValues.get(i)).getValue().equals("Tuesday"))
				strDates[i - 1] = 2;
			else if (((StringAttribute) argValues.get(i)).getValue().equals("Wednesday"))
				strDates[i - 1] = 3;
			else if (((StringAttribute) argValues.get(i)).getValue().equals("Thursday"))
				strDates[i - 1] = 4;
			else if (((StringAttribute) argValues.get(i)).getValue().equals("Friday"))
				strDates[i - 1] = 5;
			else if (((StringAttribute) argValues.get(i)).getValue().equals("Saturday"))
				strDates[i - 1] = 6;
		}
		
		// so sanh middleDay voi cac gia tri trong day strDates
		for (int j = 0; j < strDates.length; j++) {
			if (middleDay == strDates[j]) {
				return EvaluationResult.getInstance(middleDay == strDates[j]);
			}
		}
		
		//neu khong bang nhau thi di den day
		return EvaluationResult.getInstance(false);
	}

	public EvaluationResult evalArgs(List params, EvaluationCtx context,
			ArrayList<AttributeValue> argValues) {
		Iterator it = params.iterator();
	
		while (it.hasNext()) {
			// get and evaluate the next parameter
			Evaluatable eval = (Evaluatable) (it.next());
			EvaluationResult result = eval.evaluate(context);

			// If there was an error, pass it back...
			if (result.indeterminate())
				return result;

			if (result.getAttributeValue() instanceof StringAttribute) {
				argValues.add((StringAttribute) result.getAttributeValue());
			} else if (result.getAttributeValue() instanceof BagAttribute) {
				/** Neu tham so dau vao la AttributeSelector thi tra ve cac gia
				 * tri trong bag vao mang args[]
				 */
				BagAttribute bag = (BagAttribute) result.getAttributeValue();
				Iterator iterator;
				iterator = bag.iterator();
				while (iterator.hasNext()) {
					argValues.add((DateAttribute) iterator.next());
				}
			}
		}
		// if no error occurred then we got here, so we return no errors
		return null;
	}

	public void checkInputs(List inputs) throws IllegalArgumentException {
		// check that none of the inputs is a bag
		Object[] list = inputs.toArray();
		for (int i = 0; i < list.length; i++) {
			if (list[i] instanceof AttributeSelector) {
				if (!((AttributeSelector) (list[i])).evaluatesToBag())
					throw new IllegalArgumentException("can't use bags");
			}
		}
	}

}
